home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-17 | 10.7 KB | 391 lines | [TEXT/MPS ] |
- /*
- From: bhamlin@netcom.com (Brian Hamlin)
- To: tcl-talk@brown.edu, shayer@applelink.apple.com
- Subject: debugging DCMD srcs
-
- B. Marshall Hamlin
- Constructor, Noesis Sfwr Construction
-
- 6300 Leona St
- Oakland, CA 94605-1228
-
- All:
-
- Have you ever been frustrated in debugging TCL situations, breaking
- on something like CView::Activate() 27 times, and on the 28th low-and-
- behold there is your bug, but the debugger tells you the object is a,
- you guessed it, CView! The stack crawl is ok, if you can see past some
- factorial number of DispatchClicks, DoCommands and the like. What *I*
- really wanted was the name of my !@^%#$& object !
-
- So here it is: a DCMD that gives the name of an object, passed the
- object's *actual* address in the heap (when the debugger says
- struct 0x0112345)
-
- NOTE: executing Debugger macro __cn(this) shows the current
- object's name in the src level debugger (!)
-
- */
-
- /*
- tclObjName DCMD
-
- USAGE:
-
- pass in the addr of an object on the heap and this dcmd returns
- the object's class name. A5 must be current.
-
- pass in no address and this DCMD looks through the application
- heap for possible tcl objects and writes a list to output.
-
- TCL Library code for class_name(). Given the short in the first two
- bytes of the object handle, return the address of the class name in D0.
-
- MOVEA 4(A7),A0 ; get object ID
- ADDA.L A5,A0 ; find ptr at ID(A5)
- MOVEQ #1,D0 ;
- ADD (A0)+,D0 ; off2 = *p + 1
- LSL #2,D0 ; off2 *= 4
- ADDA.W D0,A0 ; find obj record
- MOVEQ #16,D0 ; name at offset 0x10
- ADD.L A0,D0 ; return name ptr
- RTS
-
-
- FIX:
-
- -detect non ascii chars in potential class-name
- -show all _still_ questionable blocks with a '?'
- -find bug in globals !
- -allow a string to be passed as a match patt for class names
-
-
- CREATED: 28apr92 bh
-
- Copyright 1992, Noesis
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
-
- */
-
- // B E G I N L I S T I N G
- // ***************************************************************************
-
- #include <Types.h>
- #include "dcmd.h"
-
- #define tclBadAddrM(ADDR) (ADDR<*(long*)0x2AA || ADDR>*(long*)0x130)
-
- //***************************************************************************
- // F O R W A R D
- pascal void doObjectMap(void);
- Boolean tclBadAddr( long addr);
- void doFindObject( long addr);
- pascal void ObjectSearch(long blockAddress, long blockLength, long addrOfMasterPtr, short blockType, Boolean locked, Boolean purgeable, Boolean resource);
-
-
-
- //**************************************************************************
- // S T A T I C
- static long gObjCnt;
- static unsigned long gObjSize;
-
- static char gMatchChars[ 34];
-
-
- /***************************************************************************
- CommandEntry
- ***************************************************************************/
- pascal void CommandEntry (dcmdBlock* paramPtr)
- {
- long address;
- short ch;
- Boolean ok;
- char c;
-
-
- switch (paramPtr->request) {
-
- case dcmdInit:
- break;
-
- case dcmdHelp:
- dcmdDrawLine ("\ptclObjName objAddr");
- dcmdDrawLine ("\p Display class name of a TCL object, bh 19jun92");
- break;
-
- case dcmdDoIt:
-
- gObjCnt = 0;
- gObjSize = 0;
-
- dcmdSwapWorlds();
- if ( paramPtr->registerFile[A5Register] != *(long*)0x904){
- dcmdDrawLine ("\p#tclObjName - A5 world not current");
- return;
- }
-
- // *******************************************************
- // No Params - do a heap map
-
- if ( (c=dcmdPeekAtNextChar()) == '\n') {
- doObjectMap();
- return;
- }
-
- // *******************************************************
- // Numeric Param - find an address
-
- if ( isdigit(c) ) {
- ch = dcmdGetNextExpression (&address, &ok);
- if (!ok) {
- dcmdDrawLine ("\p#tclObjName - Syntax error");
- return;
- }
- doFindObject( address);
- return;
- }
-
- // *******************************************************
- // Alpha Param - Match a string in Object Name
-
-
- break;
- }
- }
-
-
- /***************************************************************************
- tclBadAddr
- ***************************************************************************/
- Boolean tclBadAddr( long addr)
- {
- return (addr<*(long*)0x2AA || addr>*(long*)0x130);
- }
-
-
- /***************************************************************************
- doFindObject
- ***************************************************************************/
- void doFindObject( long addr)
- {
- unsigned long p1, p2;
-
- // ******************************************************************
- // Find a single Object's name
-
- if ( !tclBadAddr( addr)) {
- dcmdDrawLine ("\p#tclObjName - objAddr not in application heap!");
- return;
- }
-
- p1 = *(short*)addr + *(long*)0x904;
- p2 = (*(short*)p1++ + 1)<<2;
- p2 += p1;
- PutCStr( (char*)p2+16); PutLine();
-
- //dcmdDrawLine( (unsigned char*)((char*)p2+16)); // really a c string
- dcmdDrawLine( "\p*** tclObjName ***");
- }
-
-
- /***************************************************************************
- ObjectSearch
- ***************************************************************************/
- pascal void
- ObjectSearch(long blockAddress, long blockLength, long addrOfMasterPtr,
- short blockType, Boolean locked, Boolean purgeable, Boolean resource)
- {
- unsigned long p1, p2;
- char *s;
- short cnt, c;
-
- if (blockType != relocatableBlock)
- return;
- //if ( *(short*)blockAddress > 0)
- // return;
-
- p1 = *(short*)blockAddress + *(long*)0x904;
- //if ( tclBadAddrM( p1)) { PutLine(); return;}
- p2 = (*(short*)p1++ + 1)<<2;
- p2 += p1;
- //if ( tclBadAddr( p2)) { PutLine(); return;}
- s = (char*)p2+16+1; // what's with the 1 ?
-
- cnt = strlen(s);
- if ( *s < 'A' || *s > 'Z' || cnt < 3 ) { return;}
- for ( c=0;c<cnt;c++)
- if ( !isalpha( s[c]))
- return;
-
- PutChar( (locked)?('L'):(' '));
- PutChar( (blockLength>0x400)?('?'):(' '));
-
- PutCStrTruncTo( s, 32);
- PutSpacesTo( 35);
- //PutUHexZTo( blockLength, 0, 42);
- PutUHexZ( blockLength, 8);
- PutSpacesTo( 46);
- PutUHexZ( blockAddress, 8);
- PutLine();
-
- gObjCnt++;
- gObjSize += blockLength;
-
- // fake refs section
- if (0) {
- long l; Boolean b;
-
- l = blockAddress; l = blockLength; l = addrOfMasterPtr; l = blockType;
- b = locked; b = purgeable; b = resource;
- }
-
- return;
- }
-
- /***************************************************************************
- doObjectMap
- ***************************************************************************/
- pascal void doObjectMap()
- {
-
- dcmdDrawLine((char*)0x910);
- dcmdDrawLine("\p");
-
- // 1 2 3 4 5 6 7
- // 01234567890123456789012345678901234567890123456789012345678901234567890
- dcmdDrawLine("\p Object Name Size Addr");
- dcmdDrawLine("\p------------------------------------------------------");
-
- dcmdForAllHeapBlocks( ObjectSearch);
- dcmdDrawLine("\p------------------------------------------------------");
-
- if ( !gObjCnt) {
- dcmdDrawLine("\pNo objects found - Are we really in Kansas, Toto ?");
- dcmdDrawLine("\p");
- return;
- }
- PutCStr( "Heap Objects found: ");
- PutUDec( gObjCnt);
- PutLine();
- PutCStr( "Heap Objects sizes: ");
- PutUDec( gObjSize);
- PutLine();
- PutCStr( "Total heap size:");
- PutUDec( *(long*)0x130 - *(long*)0x2AA);
- PutLine();
-
- }
-
-
- // ***************************************************************************
- /* B U I L D
- [
- #getfilename
-
- set dcmdLib 'HD_80:MacsBug 6.2.2:dcmds:dcmd Libraries:'
- set srcDir 'Srcs Shuttle:tclObjNameƒ:'
-
- #set dcmdLib Alliance:MacsBugƒ:dcmdƒ:
- #set srcDir Alliance:Telecom:Netcomƒ:tcl-talk:
-
- #directory {dcmdLib}
- # C put.c -b
-
- directory "{srcDir}"
-
- C tclObjName.c -b
- Link "{dcmdLib}"dcmdGlue.a.o "{dcmdLib}"put.c.o ∂
- tclObjName.c.o "{dcmdLib}"DRuntime.o ∂
- "{CLibraries}"StdCLib.o "{Libraries}"Interface.o -o tclObjName
- "{dcmdLib}"BuildDcmd tclObjName 3200
-
- #Rez -ov -a -o 'Alliance:Systemƒ:TMON Folder:HG dcmds & templates'∂
- # tclObjName
- 'Alliance:Tools:ResEdit 2.1.1$cs' 'Alliance:Systemƒ:TMON Folder:HG dcmds & templates' tclObjName
-
- ]
-
- {dcmdLib}TestDcmd
-
- 'Alliance:Tools:ResEdit 2.1.1$cs' {dcmdLib}"Debugger Prefs" tclObjName
-
- dumpobj {Libraries}Interface.o
- dumpobj {CLibraries}StdCLib.o
- set
-
-
- -----------------------------------------------------------------------------
- DCMD Put Library
- Copyright © 1988 Apple Computer, Inc. All rights reserved.
- -----------------------------------------------------------------------------
-
- o PutLine()
- Write Put Library line buffer to output
-
- o PutChar(char c)
- Add 1 char to the line buffer
-
- o PutSpace()
- Add 1 space to the line buffer
-
- o PutSpacesTo(int pos)
- Add spaces to a position in the line buffer. Tab.
-
- o PutBytesTruncTo(const char* s, int len, int pos)
- Put string, ending at a line buffer position. Truncate or pad.
-
- o PutBytesTo(const char* s, int len, int pos)
- Put string, writing past position if necessary or pad.
-
- o PutCStrTo(const char* s, int pos)
- Write C String to line buffer. Uses PutBytesTo().
-
- o PutCStrTruncTo(const char* s, int pos)
- Write string, truncate of necessary. Uses PutBytesTruncTo().
-
- o PutCStr(const char* s)
- Write C String to line buffer, never pad.
-
- o PutPStrTruncTo(const char* s, int pos)
- Write pascal string, uses PutBytesTruncTo().
-
- o PutPStrTo(const char* s, int pos)
- Write pascal string, uses PutBytesTo().
-
- o PutPStr(const char* s)
- Write pascal string, uses PutBytesTo().
-
- o PutUHexZTo(unsigned long i, int ndig, int pos)
- Write unsigned hex string ending at position.
- ndig -> number of digits in string
- Bug: no check for linepos > pos
-
- o PutUHexZ(unsigned long i, int nz)
- Write unsigned hex string, uses PutUHexZTo()
- nz -> number of digits in string
-
- o PutUHexWord(unsigned long i)
- Write 2 bytes as Unsigned Hex, uses PutUHexZTo().
-
- o PutUDecTo(unsigned long i, int pos)
- Write decimal string ending at position.
- Bug: no check for linepos > pos
-
- o PutUDec(unsigned long i)
- Write decimal string, uses PutUDecTo().
-
- o PutOSType(unsigned long typ)
- Write 4 bytes as chars, no conversion. Uses PutChar().
-
- */
- // ***************************************************************************
- // E N D O F L I S T I N G
-
-
-